package com.panopset.sf;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.HierarchyBoundsAdapter;
import java.awt.event.HierarchyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;

import com.panopset.Zombie;

/**
 * Resizable Osgw panel.
 *
 * @author Karl Dinwiddie
 *
 */
public abstract class OsgwResizable {

    /**
     * 300 test size.
     */
    private static final int TS = 300;

    public OsgwResizable() {
        getPanel().addHierarchyBoundsListener(new HierarchyBoundsAdapter() {
            @Override
            public void ancestorResized(final HierarchyEvent e) {
                update();
            }
        });
        update();
    }

    /**
     *
     * @param s
     *            Not used.
     */
    public static void main(final String... s) {
        JFrame f = new JFrame();
        f.setLocation(TS, TS);
        f.setSize(TS, TS);
        f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        f.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosed(final WindowEvent e) {
                Zombie.stop();
            }
        });
        f.setTitle("OsgwResizable test");
        f.add(new OsgwResizable() {

            @Override
            public void paintCycle(final Graphics2D g) {
                g.setColor(Color.RED);
                g.fillRect(0, 0, getPanel().getWidth(), getPanel().getHeight());
                g.setColor(Color.YELLOW);
                g.fillOval(0, 0, getPanel().getWidth(), getPanel().getHeight());
            }
        }

        .getPanel());
        f.setVisible(true);
    }

    /**
     * Off screen graphics world.
     */
    private Osgw osgw;

    /**
     *
     * @return Off screen graphics world.
     */
    public final Osgw getOsgw() {
        if (osgw == null) {
            osgw = new Osgw(getPanel().getSize()) {

                @Override
                public void paintCycle(final Graphics2D g) {
                    OsgwResizable.this.paintCycle(g);
                }

            };
        }
        return osgw;
    }

    /**
     *
     * @param g
     *            Graphics2D.
     */
    public abstract void paintCycle(Graphics2D g);

    /**
     * Bound parent size.
     */
    private Dimension boundParentSize;

    /**
     * Update.
     */
    private void update() {
        if (panel == null) {
            return;
        }
        if (panel.getSize().height == 0) {
            return;
        }
        if (panel.getSize().width == 0) {
            return;
        }
        if (boundParentSize != null
                && getPanel().getSize().equals(boundParentSize)) {
            return;
        }
        panel.removeAll();
        osgw = null;
        panel.add(getOsgw().getPanel());
        boundParentSize = getPanel().getSize();
        getPanel().invalidate();
        getPanel().getTopLevelAncestor().validate();
    }

    /**
     * Panel.
     */
    private JPanel panel;

    /**
     * @return Panel that contains the Osgw.
     */
    public final JPanel getPanel() {
        if (panel == null) {
            panel = new JPanel(new GridLayout(1, 1));
        }
        return panel;
    }
}
